using System;
using System.Linq;
using System.Web.Mvc;
using AutoMapper;
using HeadspringExample.Core.Domain;
using HeadspringExample.Core.Domain.Model;
using HeadspringExample.Infrastructure.DataAccess.Repositories;
using HeadspringExample.UI.Helpers;
using HeadspringExample.UI.Models;
using Microsoft.Web.Mvc;
using NHibernate;

namespace HeadspringExample.UI.Controllers
{
    public class ConferenceController : DefaultController
    {
		private readonly IConferenceRepository _repository;

		public ConferenceController(IConferenceRepository repository)
		{
			_repository = repository;
		}

		// Before controller factories

		//private readonly ConferenceRepository _repository;

		//public ConferenceController()
		//{
		//    _repository = new ConferenceRepository(Sessions.Current);
		//}

		// Before model binding

		//public ViewResult Show(string eventName)
		//{
		//    var conference = _repository.GetByName(eventName);

		//    var viewModel = Mapper.Map<Conference, ConferenceShowModel>(conference);

		//    return View(viewModel);
		//}

		// After model binding

		//public ViewResult Show(Conference eventName)
		//{
		//    var viewModel = Mapper.Map<Conference, ConferenceShowModel>(eventName);

		//    return View(viewModel);
		//}


		// Before AutoMapper

		//public ActionResult Edit(string confname)
		//{
		//    var conf = _repository.GetByName(confname);

		//    var model = new ConferenceEditModel
		//    {
		//        Id = conf.Id,
		//        Name = conf.Name,
		//        Attendees = conf.GetAttendees()
		//            .Select(a => new ConferenceEditModel.AttendeeEditModel
		//            {
		//                Id = a.Id,
		//                FirstName = a.FirstName,
		//                LastName = a.LastName,
		//                Email = a.Email,
		//            }).ToArray()
		//    };

		//    return View(model);
		//}

		// After AutoMapper

		//public ActionResult Edit(string confname)
		//{
		//    var conf = _repository.GetByName(confname);

		//    var viewModel = Mapper.Map<Conference, ConferenceEditModel>(conf);

		//    return View(viewModel);
		//}

		// Before simplification

		//[HttpPost]
		//public ActionResult Register(AttendeeEditModel model)
		//{
		//    if (ModelState.IsValid)
		//    {
		//        var entity = _repository.GetById(model.EventId);
		//        var attendee = new Attendee(model.FirstName, model.LastName)
		//        {
		//            Email = model.Email
		//        };
		//        attendee.RegisterFor(entity);
		//        return RedirectToAction("AttendeeConfirmation", model);
		//    }

		//    return View(model);
		//}

		public AutoMapViewResult Index(int minSessions = 0)
		{
			var list = from conf in _repository.Query()
					   where conf.SessionCount >= minSessions
					   select conf;

			return AutoMapView<ConferenceListModel[]>(View(list.ToArray()));
		}

		public AutoMapViewResult Show(Conference eventName)
		{
			return AutoMapView<ConferenceShowModel>(View(eventName));
		}

		public AutoMapViewResult Edit(Conference eventname)
        {
			return AutoMapView<ConferenceEditModel>(View(eventname));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(ConferenceEditModel form)
        {
			var success = this.RedirectToAction(c => c.Index(0), "Default");
			
			return Form(form, success);
        }

        public ViewResult Register(Conference eventName)
        {
            return View(new AttendeeEditModel
            {
				EventId = eventName.Id,
				EventName = eventName.Name
            });
        }

		[HttpPost]
		public ActionResult Register(AttendeeEditModel model)
		{
			var success = this.RedirectToAction(
				c => c.AttendeeConfirmation(model.FirstName,
					model.LastName, model.EventName));

			return Form(model, success);
		}

        public ViewResult AttendeeConfirmation(string firstName, string lastName, string eventName)
        {
			var model = new AttendeeConfirmationModel
			{
				FirstName = firstName,
				LastName = lastName,
				EventName = eventName
			};
            return View(model);
        }
    }

	public class Sessions
	{
		public static ISession Current { get; set; }
	}

}
